package com.aldobucchi.graph.tree
{
	
	import flash.utils.Dictionary;
	
	import mx.collections.ICollectionView;
	import mx.controls.treeClasses.ITreeDataDescriptor;
	
	import com.aldobucchi.graph.QueryCollectionView;
	import com.aldobucchi.graph.query.IQueryTarget;
	import com.aldobucchi.graph.query.Query;
	import com.aldobucchi.utils.Arc;




	/**
	 * 
	 * TODO: add a way to pass priority
	 * 
	 * @author aldo.bucchi@gmail.com
	 * 
	 */
	public class GraphTreeDataDescriptor  implements ITreeDataDescriptor
	{

		
		private var arc:Arc;
		
		private var queryTarget:IQueryTarget;
		
		
		
		private var nodeChildrenCache:Dictionary = new Dictionary( true );
		
		
		
		public function GraphTreeDataDescriptor( arc:Arc, queryTarget:IQueryTarget = null )
		{
			this.arc = arc;
			this.queryTarget = queryTarget == null ? Query.defaultTarget : queryTarget;	
		}
		
		
		
		
		
		private function resolveNode( node:* ):*
		{
			return node;
		}
		
		
		
		
		public function getChildren( node:Object, model:Object=null ):ICollectionView
		{

			node = resolveNode( node );
			
			if ( !nodeChildrenCache[ node ] )
			{
				var q:Query = new Query( queryTarget );
				q.simpleQueryArc 	= arc;
				q.simpleQueryNode 	= node;
				nodeChildrenCache[ node ] = QueryCollectionView.forQuery( q );
			}
		
			return nodeChildrenCache[ node ];
		
		}
		


		public function hasChildren(node:Object, model:Object=null):Boolean
		{
			return true; // can we throw an item pending error?
		}
		
		
		
		public function isBranch(node:Object, model:Object=null):Boolean
		{
			return true;
		}
		
		
		
		public function getData(node:Object, model:Object=null):Object
		{
			return resolveNode( node );			
		}
		
		
		
		
		



		
		public function removeChildAt(parent:Object, child:Object, index:int, model:Object=null):Boolean
		{
			return false;
		}
		
		public function addChildAt(parent:Object, newChild:Object, index:int, model:Object=null):Boolean
		{
			return false;
		}

	}
}